const path = require('path')
const fs = require('fs')
const Uglify = require('uglify-js')
const bathPath = path.join(__dirname)
const compressResult = { fileNumber: 0, rate: 0 }
const init = () => {
  console.log(`------compress start at ${new Date()}------`)
  loopModuleFile(bathPath).then(() => {
    console.log(`压缩文件数：${compressResult.fileNumber}，压缩率：${(compressResult.rate * 100).toFixed(2)}%`)
    console.log(`------compress end at ${new Date()}------`);
  }, () => {
    console.log(`压缩文件数：${compressResult.fileNumber}，压缩率：${(compressResult.rate * 100).toFixed(2)}%`)
    console.log(`------compress end at ${new Date()}------`);
  })
}
const loopModuleFile = modulePath => {
  return new Promise((resolve, reject) => {
    const packages = fs.readFileSync(path.join(modulePath, 'package.json'))
    const dependencies = JSON.parse(packages.toString()).dependencies
    if (dependencies) {
      const dependenciesKey = Object.keys(dependencies)
      dependenciesKey.forEach((item, index) => {
        console.log('module:', item)
        const parentPath = path.join(__dirname, 'node_modules', item)
        loopFolder(parentPath).then(() => {
          if (index === dependenciesKey.length - 1) {
            resolve()
          }
        }, (e) => {
          console.error(e)
          if (index === dependenciesKey.length - 1) {
            reject(e)
          }
        })
      })
    } else {
      resolve()
    }
  })
}
const loopFolder = folderPath => {
  return new Promise((resolve, reject) => {
    console.log(folderPath)
    const dirs = fs.readdirSync(folderPath)
    if (!dirs || dirs.length <= 0) {
      resolve()
      return
    }
    dirs.forEach((innerItem, index) => {
      const wholePath = path.join(folderPath, innerItem)
      if (fs.lstatSync(wholePath).isDirectory()) {
        if (innerItem === 'node_modules') {
          fs.rmdir(wholePath,()=>{console.warn(`-------------------sub node_modules deleted.${wholePath}`)})
        } else {
          loopFolder(path.join(folderPath, innerItem)).then(() => {
            if (index === dirs.length - 1) { resolve() }
          }, (e) => {
            if (index === dirs.length - 1) { reject(e) }
          })
        }
      } else {
        compress(folderPath, innerItem).then(() => {
          if (index === dirs.length - 1) { resolve() }
        }, (e) => {
          if (index === dirs.length - 1) { reject(e) }
        })
      }
    })
  })
}
const compress = (parentPath, fileName) => {
  return new Promise((resolve, reject) => {
    fs.readFile(path.join(parentPath, fileName), (err, filecontent) => {
      console.log('------------')
      console.log(path.join(parentPath, fileName))
      if (err) {
        reject(err)
        return
      }
      try {
        if (fileName.indexOf('\.') === -1) {
          console.log(`No file extention found. file name ${fileName}`)
          resolve()
          return
        }
        const fileNameSplitArr = fileName.split('\.')
        const extention = fileNameSplitArr[fileNameSplitArr.length - 1]
        let result
        switch (extention) {
          case 'js': result = Uglify.minify(filecontent.toString()).code; break
          case 'json': result = JSON.stringify(JSON.parse(filecontent.toString())); break
          default: console.log(`Unsupported file extention ${fileName}`);
        }
        if (result) {
          compressResult.fileNumber++
          console.log(compressResult.fileNumber)
          const rate = (result.length / filecontent.length) * 100
          compressResult.rate = ((compressResult.rate * 100) + rate) / 200
          console.log(
            'before:',
            filecontent.length,
            'after:',
            result.length,
            'rate:',
            rate.toFixed(2) + '%'
          )
          fs.writeFile(path.join(parentPath, fileName), result, err => {
            if (err) {
              reject(err)
            } else {
              resolve()
            }
          })
        } else {
          reject(new Error(`context is invalid.\nparentPath:${parentPath}\nfileName${fileName}context:${result}`))
        }
      } catch (e) {
        reject(e)
      }
    })
  })
}
init()
